<?php
/***
Plugin Name: openxwpwidget
Plugin URI: http://www.openx.org/
Description: Sidebar-Widget, display a banner in a sidebar and replace magics {openx:zoneid} with calls to a openx adserver
Version: 0.1
Author: Heiko Weber, heiko@wecos.de
Author URI: http://www.wecos.de
Update Server: http://www.openx.org/...
Min WP Version: 2.5.0
Max WP Version: 2.5.0
***/

/***
+---------------------------------------------------------------------------+
| OpenX v2.5                                                                |
| ==========                                                                |
|                                                                           |
| Copyright (c) 2003-2008 OpenX Limited                                     |
| For contact details, see: http://www.openx.org/                           |
|                                                                           |
| This program is free software; you can redistribute it and/or modify      |
| it under the terms of the GNU General Public License as published by      |
| the Free Software Foundation; either version 2 of the License, or         |
| (at your option) any later version.                                       |
|                                                                           |
| This program is distributed in the hope that it will be useful,           |
| but WITHOUT ANY WARRANTY; without even the implied warranty of            |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             |
| GNU General Public License for more details.                              |
|                                                                           |
| You should have received a copy of the GNU General Public License         |
| along with this program; if not, write to the Free Software               |
| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA |
+---------------------------------------------------------------------------+
$Id$
*/

/** widget initialization moved into one function,
 *  registered below at the end of the file.
 */
function widget_openxwpwidget_init() {

    if ( !function_exists('register_sidebar_widget')
      || !function_exists('register_widget_control') )
            return;

    /** this widget callback function gets called to output
     *  the "widget content" to the sidebar, so this are actually
     *  one or more banners (invocationcodes)
     */
    function widget_openxwpwidget($args)
    {
        // extract the args, magic? but this is Wordpress API ...
        extract($args);

        // retrieve our widget options and settings
        $location = stripslashes(get_option('openxwpwidget_url2openx'));
        $options = get_option('widget_openxwpwidget');

        // how many banners/zones should we show
        $zoneCount = empty($options['zonecount']) ? 0 : $options['zonecount'];

        // loop over there ...
        $bannercode = '';
        for ($n = 0; $n < intval($zoneCount); $n++) {
            $zoneID = empty($options['zoneid'.$n]) ? '' : $options['zoneid'.$n];
            $bannercode .= _openxwpwidget_get_invocation($location, $zoneID);
        }

        // done, most of the echo's are framework
        echo $before_widget;
        echo $before_title;
        echo $bannercode;
        echo $after_title;
        echo $after_widget;
    }

    /** small helper function, returns a javascript invocationcode
     *
     *  @param string  $location path to the adservers delivery directory
     *  @param integer $zoneID   ID of the zone
     *
     *  @return string javascript invocation code
     */
    function _openxwpwidget_get_invocation($location, $zoneID)
    {
        if (empty($location) || $location == '' || intval($zoneID) == 0)
            return '';

        $random = md5(rand(0, 999999999));
        $n = substr(md5(rand(0, 999999999)), 0, 6);

        return "
<!--/* OpenX Javascript Tag v2.5.60-beta */-->

<script type='text/javascript'><!--//<![CDATA[
   var m3_u = (location.protocol=='https:'?'https://" . $location . "/ajs.php':'http://" . $location . "/ajs.php');
   var m3_r = Math.floor(Math.random()*99999999999);
   if (!document.MAX_used) document.MAX_used = ',';
   document.write (\"<scr\"+\"ipt type='text/javascript' src='\"+m3_u);
   document.write (\"?zoneid=". $zoneID ."\");
   document.write ('&amp;cb=' + m3_r);
   if (document.MAX_used != ',') document.write (\"&amp;exclude=\" + document.MAX_used);
   document.write (\"&amp;loc=\" + escape(window.location));
   if (document.referrer) document.write (\"&amp;referer=\" + escape(document.referrer));
   if (document.context) document.write (\"&context=\" + escape(document.context));
   if (document.mmm_fo) document.write (\"&amp;mmm_fo=1\");
   document.write (\"'><\/scr\"+\"ipt>\");
//]]>--></script><noscript><a href='http://$location/ck.php?n=$n&amp;cb=$random' target='_blank'><img src='http://" . $location . "/avw.php?zoneid=$zoneID&amp;cb=$random&amp;n=$n' border='0' alt='' /></a></noscript>";
    }


    /** this function install the callback-function openxwp_adminsection
     *  for a admin setup page for this plugin
     */
    function openxwpwidget_admin_menuitem()
    {
        if (function_exists('add_options_page')) {
            add_options_page('options-general.php', 'OpenX-WP', 8, basename(__FILE__), 'openxwpwidget_adminsection');
            add_action( "admin_print_scripts", 'openxwpwidget_admin_head' );
        }
    }

    /** this callback function adds some javascript to
     *  the head section (wp-admin-pages only). I've tried
     *  to add this code only for openxwpwidget-pages, but
     *  didn't find a reference-guide how this really work.
     *  So, it gets always added ...
     */
    function openxwpwidget_admin_head()
    {
        ?>
<script type="text/javascript"><!--//<![CDATA[
function openxwpwidget_returnObjByName(name)
{
    if (document.getElementsByName)
       var returnVar = document.getElementsByName(name);
    else if (document.all)
       var returnVar = document.all[name];
    else if (document.layers)
       var returnVar = document.layers[name];
  return returnVar;
}
function openxwpwidget_toggle_visible(whichLayer, on_off) {
  var elem = openxwpwidget_returnObjByName(whichLayer);
  if (elem && elem.length > 0) {
    var item = elem[0];
    var vis = item.style;
    // if the style.display value is blank we try to figure it out here
    if(vis.display==''&&elem.offsetWidth!=undefined&&elem.offsetHeight!=undefined)
      vis.display = (elem.offsetWidth!=0&&elem.offsetHeight!=0)?'inline':'none';
    if (!on_off)
      on_off = (vis.display!='none') ? -1 : 1;
    vis.display = (on_off < 0)?'none':'inline';
  }
}
function openxwpwidget_showhide_zones(box) {
    var zonecount = box.options[box.selectedIndex].value;
    for (n = 0; n < 10; n++) {
        openxwpwidget_toggle_visible('openxwpwidget-div-zoneid'+n, (zonecount > n) ? 1 : -1);
    }
}
//]]>-->
</script>
        <?php
    }

    /**
     * this callback function gets called for every real content
     * delivered to normal users. The callback will be installed
     * below (near end-of-file)
     *
     * @param string the content
     *
     * @return string the (maybe un-) modified content
     */
    function openxwpwidget_replace_magic($content)
    {
       // find the magic zone-tags somehow, we replace {openx:NNN}
       // with a invocationcode, whereas NNN is a zoneID
       if (($matches = preg_match_all('/\{openx\:(\d+)\}/', $content, $aResult)) !== false) {
           $content = _openxwpwidget_replace_zones($content, $aResult);
       }

       return $content;
    }

    /**
     * this function replace any magic openx-zones in the given content
     *
     * @param string the content
     * @param array of strings with zone-numbers found in content
     *
     * @return string the (maybe un-) modified content
     */
    function _openxwpwidget_replace_zones($content, $aZones)
    {
        $url2openx = get_option('openxwpwidget_url2openx');
        $url2openx = stripslashes($url2openx);

        // prepare our search/replacement, with perl I would have
        // used a closure to replace it in a single-path
        $from = array();
        $to = array();

        foreach ($aZones as $hits) {
            $zoneID = $hits[0];
            $random = md5(rand(0, 999999999));
            $from[] = '{openx:' . $zoneID . '}';
            $to[]   = _openxwpwidget_get_invocation($url2openx, $zoneID);
        }
        return str_replace($from, $to, $content);
    }


    /** this function represents the admin setup page for this
     *  plugin.
     */
    function openxwpwidget_adminsection()
    {
        add_option('openxwpwidget_url2openx', '');

        if (isset($_POST['openxwpwidget_url2openx'])) {
            $url2openx = $_POST['openxwpwidget_url2openx'];
            // remove a trailing http://, internally we use it without
            $url2openx = preg_replace('/^https?:\/\//', '', $url2openx);
            update_option('openxwpwidget_url2openx', $url2openx);
        }
        $url2openx = stripslashes(get_option('openxwpwidget_url2openx'));

        // uh, I am not a web-designer, so someone else pick up this
        // part please ...
        ?>

<STYLE TYPE="TEXT/CSS">
div#openxwpwidget b {
        color: red;
}
</STYLE>

<DIV CLASS="wrap">
  <DIV id="poststuff">
    <DIV id="openxwpwidget">
       <p>
       Type the path to your adservers delivery directory into the
       textfield.</p>
       <p>Sample path to adserver: <b>ads.openx.org/delivery.</b></p>
       <p>Now you simply add ad-code into your content like
       <b>{openx:N}</b>, whereas <b>N</b> is a zoneID at your
       adserver.</p>
       <p>In addition, this plugin acts as a widget, so you can add
       it to a sidebar.</p>

      <FORM name="openxwpwidget_form" method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>?page=openx-wp-widget.php&updated=true">
         <p>Url to OpenX-AdServer:</p>
         <input type=textfield size="60" name="openxwpwidget_url2openx" id="url2openx" value="<?php echo $url2openx; ?>">
         <p>&nbsp;</p>
         <input type="submit" name="submit" value="Save" />
      </FORM>
    </DIV>
  </DIV>
</DIV>

      <?php
    }

    /** This function controls the sidebar functionality,
     *  admin-part. Show and save of the options.
     */
    function widget_openxwpwidget_control()
    {
       $options = get_option('widget_openxwpwidget');
       if (!is_array($options)) {
           $options = array('zonecount' => 0);
       }

       // save our stuff
       if ( $_POST['openxwpwidget-submit'] ) {
           $newoptions['url2openx'] = strip_tags(stripslashes($_POST['openxwpwidget-url2openx']));
           $newoptions['zonecount'] = strip_tags(stripslashes($_POST['openxwpwidget-zonecount']));
           for ($n = 0; $n < intval($newoptions['zonecount']); $n++)
               $newoptions['zoneid'.$n] = strip_tags(stripslashes($_POST['openxwpwidget-zoneid'.$n]));

           if (array_diff_assoc($options, $newoptions) !== array_diff_assoc($newoptions, $options)) {
               $options = $newoptions;
               update_option('widget_openxwpwidget', $options);
           }
       }

       // prepare our settings to show them at the admin-page
       // we prepare up to 10 zones, and use javascript/style to
       // show or hide them, because if the users changes the
       // total zonecode he like to use, we can't submit to
       // change the number of offered zones.

       $url2openx = htmlspecialchars($options['url2openx'], ENT_QUOTES);
       $zonecount = htmlspecialchars($options['zonecount'], ENT_QUOTES);
       for ($n = 0; $n < intval($zonecount); $n++)
           $zoneID[$n] = htmlspecialchars($options['zoneid'.$n], ENT_QUOTES);
       ?>
       <div>
          <label for="openxwpwidget-zonecount">Number of banners:<br />
             <select name="openxwpwidget-zonecount" id="openxwpwidget-zonecount" onchange="openxwpwidget_showhide_zones(this);">
                <?php
                  for ($n = 0; $n <= 10; $n++) {
                      $sel = ($n == $zonecount) ? 'selected' : '';
                      echo "<option value='$n' $sel>$n</option>\n";
                  }
                ?>
             </select>
          </label>
          <br /><br />
          <?php
          for ($n = 0; $n < 10; $n++) {
              $showhide = (intval($zonecount) > $n) ? 'inline' : 'none';
              $n1 = $n+1;
              echo "<div id='openxwpwidget-div-zoneid$n' name='openxwpwidget-div-zoneid$n' style='display:$showhide;'>\n";
              echo "<label for='openxwpwidget-zoneid'>ZoneID for Banner $n1:<br />\n";
              echo "<input type='text' id='openxwpwidget-zoneid$n' name='openxwpwidget-zoneid$n' value='$zoneID[$n]' />\n";
              echo "</label>\n";
              echo "<br /></div>\n";
          }
          ?>
          <input type="hidden" name="openxwpwidget-submit" id="openxwpwidget-submit" value="true" />
       </div>
       <?php
    }

    register_sidebar_widget('OpenX Widget', 'widget_openxwpwidget');

    register_widget_control('OpenX Widget', 'widget_openxwpwidget_control');

    // and finally install our admin-setup-callback and content-filter
    add_action('admin_menu', 'openxwpwidget_admin_menuitem');
    add_filter('the_content', 'openxwpwidget_replace_magic');
}

add_action('plugins_loaded', 'widget_openxwpwidget_init');
?>
